home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / BaseClasses / winutil.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  16.1 KB  |  415 lines

  1. //------------------------------------------------------------------------------
  2. // File: WinUtil.h
  3. //
  4. // Desc: DirectShow base classes - defines generic handler classes.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9.  
  10. // Make sure that you call PrepareWindow to initialise the window after
  11. // the object has been constructed. It is a separate method so that
  12. // derived classes can override useful methods like MessageLoop. Also
  13. // any derived class must call DoneWithWindow in its destructor. If it
  14. // doesn't a message may be retrieved and call a derived class member
  15. // function while a thread is executing the base class destructor code
  16.  
  17. #ifndef __WINUTIL__
  18. #define __WINUTIL__
  19.  
  20. const int DEFWIDTH = 320;                    // Initial window width
  21. const int DEFHEIGHT = 240;                   // Initial window height
  22. const int CAPTION = 256;                     // Maximum length of caption
  23. const int TIMELENGTH = 50;                   // Maximum length of times
  24. const int PROFILESTR = 128;                  // Normal profile string
  25. const WORD PALVERSION = 0x300;               // GDI palette version
  26. const LONG PALETTE_VERSION = (LONG) 1;       // Initial palette version
  27. const COLORREF VIDEO_COLOUR = 0;             // Defaults to black background
  28. const HANDLE hMEMORY = (HANDLE) (-1);        // Says to open as memory file
  29.  
  30. #define WIDTH(x) ((*(x)).right - (*(x)).left)
  31. #define HEIGHT(x) ((*(x)).bottom - (*(x)).top)
  32. #define SHOWSTAGE TEXT("WM_SHOWSTAGE")
  33. #define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP")
  34. #define REALIZEPALETTE TEXT("WM_REALIZEPALETTE")
  35.  
  36. class AM_NOVTABLE CBaseWindow
  37. {
  38. protected:
  39.  
  40.     HINSTANCE m_hInstance;          // Global module instance handle
  41.     HWND m_hwnd;                    // Handle for our window
  42.     HDC m_hdc;                      // Device context for the window
  43.     LONG m_Width;                   // Client window width
  44.     LONG m_Height;                  // Client window height
  45.     BOOL m_bActivated;              // Has the window been activated
  46.     LPTSTR m_pClassName;            // Static string holding class name
  47.     DWORD m_ClassStyles;            // Passed in to our constructor
  48.     DWORD m_WindowStyles;           // Likewise the initial window styles
  49.     DWORD m_WindowStylesEx;         // And the extended window styles
  50.     UINT m_ShowStageMessage;        // Have the window shown with focus
  51.     UINT m_ShowStageTop;            // Makes the window WS_EX_TOPMOST
  52.     UINT m_RealizePalette;          // Makes us realize our new palette
  53.     HDC m_MemoryDC;                 // Used for fast BitBlt operations
  54.     HPALETTE m_hPalette;            // Handle to any palette we may have
  55.     BYTE m_bNoRealize;              // Don't realize palette now
  56.     BYTE m_bBackground;             // Should we realise in background
  57.     BYTE m_bRealizing;              // already realizing the palette
  58.     CCritSec m_WindowLock;          // Serialise window object access
  59.     BOOL m_bDoGetDC;                // Should this window get a DC
  60.     bool m_bDoPostToDestroy;        // Use PostMessage to destroy
  61.     CCritSec m_PaletteLock;         // This lock protects m_hPalette.
  62.                                     // It should be held anytime the
  63.                                     // program use the value of m_hPalette.
  64.  
  65.     // Maps windows message procedure into C++ methods
  66.     friend LRESULT CALLBACK WndProc(HWND hwnd,      // Window handle
  67.                                     UINT uMsg,      // Message ID
  68.                                     WPARAM wParam,  // First parameter
  69.                                     LPARAM lParam); // Other parameter
  70.  
  71.     virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message);
  72.  
  73. public:
  74.  
  75.     CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false);
  76.  
  77. #ifdef DEBUG
  78.     virtual ~CBaseWindow();
  79. #endif
  80.  
  81.     virtual HRESULT DoneWithWindow();
  82.     virtual HRESULT PrepareWindow();
  83.     virtual HRESULT InactivateWindow();
  84.     virtual HRESULT ActivateWindow();
  85.     virtual BOOL OnSize(LONG Width, LONG Height);
  86.     virtual BOOL OnClose();
  87.     virtual RECT GetDefaultRect();
  88.     virtual HRESULT UninitialiseWindow();
  89.     virtual HRESULT InitialiseWindow(HWND hwnd);
  90.  
  91.     HRESULT CompleteConnect();
  92.     HRESULT DoCreateWindow();
  93.  
  94.     HRESULT PerformanceAlignWindow();
  95.     HRESULT DoShowWindow(LONG ShowCmd);
  96.     void PaintWindow(BOOL bErase);
  97.     void DoSetWindowForeground(BOOL bFocus);
  98.     virtual HRESULT SetPalette(HPALETTE hPalette);
  99.  
  100.     void SetRealize(BOOL bRealize)
  101.     {
  102.         m_bNoRealize = !bRealize;
  103.     }
  104.  
  105.     //  Jump over to the window thread to set the current palette
  106.     HRESULT SetPalette();
  107.     void UnsetPalette(void);
  108.     virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE);
  109.  
  110.     void LockPaletteLock();
  111.     void UnlockPaletteLock();
  112.  
  113.     virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  114.         { return FALSE; };
  115.  
  116.     // Access our window information
  117.  
  118.     bool WindowExists();
  119.     LONG GetWindowWidth();
  120.     LONG GetWindowHeight();
  121.     HWND GetWindowHWND();
  122.     HDC GetMemoryHDC();
  123.     HDC GetWindowHDC();
  124.  
  125.     #ifdef DEBUG
  126.     HPALETTE GetPalette();
  127.     #endif // DEBUG
  128.  
  129.     // This is the window procedure the derived object should override
  130.  
  131.     virtual LRESULT OnReceiveMessage(HWND hwnd,          // Window handle
  132.                                      UINT uMsg,          // Message ID
  133.                                      WPARAM wParam,      // First parameter
  134.                                      LPARAM lParam);     // Other parameter
  135.  
  136.     // Must be overriden to return class and window styles
  137.  
  138.     virtual LPTSTR GetClassWindowStyles(
  139.                             DWORD *pClassStyles,          // Class styles
  140.                             DWORD *pWindowStyles,         // Window styles
  141.                             DWORD *pWindowStylesEx) PURE; // Extended styles
  142. };
  143.  
  144.  
  145. // This helper class is entirely subservient to the owning CBaseWindow object
  146. // All this object does is to split out the actual drawing operation from the
  147. // main object (because it was becoming too large). We have a number of entry
  148. // points to set things like the draw device contexts, to implement the actual
  149. // drawing and to set the destination rectangle in the client window. We have
  150. // no critical section locking in this class because we are used exclusively
  151. // by the owning window object which looks after serialising calls into us
  152.  
  153. // If you want to use this class make sure you call NotifyAllocator once the
  154. // allocate has been agreed, also call NotifyMediaType with a pointer to a
  155. // NON stack based CMediaType once that has been set (we keep a pointer to
  156. // the original rather than taking a copy). When the palette changes call
  157. // IncrementPaletteVersion (easiest thing to do is to also call this method
  158. // in the SetMediaType method most filters implement). Finally before you
  159. // start rendering anything call SetDrawContext so that we can get the HDCs
  160. // for drawing from the CBaseWindow object we are given during construction
  161.  
  162. class CDrawImage
  163. {
  164. protected:
  165.  
  166.     CBaseWindow *m_pBaseWindow;     // Owning video window object
  167.     CRefTime m_StartSample;         // Start time for the current sample
  168.     CRefTime m_EndSample;           // And likewise it's end sample time
  169.     HDC m_hdc;                      // Main window device context
  170.     HDC m_MemoryDC;                 // Offscreen draw device context
  171.     RECT m_TargetRect;              // Target destination rectangle
  172.     RECT m_SourceRect;              // Source image rectangle
  173.     BOOL m_bStretch;                // Do we have to stretch the images
  174.     BOOL m_bUsingImageAllocator;    // Are the samples shared DIBSECTIONs
  175.     CMediaType *m_pMediaType;       // Pointer to the current format
  176.     int m_perfidRenderTime;         // Time taken to render an image
  177.     LONG m_PaletteVersion;          // Current palette version cookie
  178.  
  179.     // Draw the video images in the window
  180.  
  181.     void SlowRender(IMediaSample *pMediaSample);
  182.     void FastRender(IMediaSample *pMediaSample);
  183.     void DisplaySampleTimes(IMediaSample *pSample);
  184.     void UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi);
  185.     void SetStretchMode();
  186.  
  187. public:
  188.  
  189.     // Used to control the image drawing
  190.  
  191.     CDrawImage(CBaseWindow *pBaseWindow);
  192.     BOOL DrawImage(IMediaSample *pMediaSample);
  193.     BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample,
  194.                             LPRECT lprcSrc, LPRECT lprcDst);
  195.     void SetDrawContext();
  196.     void SetTargetRect(RECT *pTargetRect);
  197.     void SetSourceRect(RECT *pSourceRect);
  198.     void GetTargetRect(RECT *pTargetRect);
  199.     void GetSourceRect(RECT *pSourceRect);
  200.     virtual RECT ScaleSourceRect(const RECT *pSource);
  201.  
  202.     // Handle updating palettes as they change
  203.  
  204.     LONG GetPaletteVersion();
  205.     void ResetPaletteVersion();
  206.     void IncrementPaletteVersion();
  207.  
  208.     // Tell us media types and allocator assignments
  209.  
  210.     void NotifyAllocator(BOOL bUsingImageAllocator);
  211.     void NotifyMediaType(CMediaType *pMediaType);
  212.     BOOL UsingImageAllocator();
  213.  
  214.     // Called when we are about to draw an image
  215.  
  216.     void NotifyStartDraw() {
  217.         MSR_START(m_perfidRenderTime);
  218.     };
  219.  
  220.     // Called when we complete an image rendering
  221.  
  222.     void NotifyEndDraw() {
  223.         MSR_STOP(m_perfidRenderTime);
  224.     };
  225. };
  226.  
  227.  
  228. // This is the structure used to keep information about each GDI DIB. All the
  229. // samples we create from our allocator will have a DIBSECTION allocated to
  230. // them. When we receive the sample we know we can BitBlt straight to an HDC
  231.  
  232. typedef struct tagDIBDATA {
  233.  
  234.     LONG        PaletteVersion;     // Current palette version in use
  235.     DIBSECTION  DibSection;         // Details of DIB section allocated
  236.     HBITMAP     hBitmap;            // Handle to bitmap for drawing
  237.     HANDLE      hMapping;           // Handle to shared memory block
  238.     BYTE        *pBase;             // Pointer to base memory address
  239.  
  240. } DIBDATA;
  241.  
  242.  
  243. // This class inherits from CMediaSample and uses all of it's methods but it
  244. // overrides the constructor to initialise itself with the DIBDATA structure
  245. // When we come to render an IMediaSample we will know if we are using our own
  246. // allocator, and if we are, we can cast the IMediaSample to a pointer to one
  247. // of these are retrieve the DIB section information and hence the HBITMAP
  248.  
  249. class CImageSample : public CMediaSample
  250. {
  251. protected:
  252.  
  253.     DIBDATA m_DibData;      // Information about the DIBSECTION
  254.     BOOL m_bInit;           // Is the DIB information setup
  255.  
  256. public:
  257.  
  258.     // Constructor
  259.  
  260.     CImageSample(CBaseAllocator *pAllocator,
  261.                  TCHAR *pName,
  262.                  HRESULT *phr,
  263.                  LPBYTE pBuffer,
  264.                  LONG length);
  265.  
  266.     // Maintain the DIB/DirectDraw state
  267.  
  268.     void SetDIBData(DIBDATA *pDibData);
  269.     DIBDATA *GetDIBData();
  270. };
  271.  
  272.  
  273. // This is an allocator based on the abstract CBaseAllocator base class that
  274. // allocates sample buffers in shared memory. The number and size of these
  275. // are determined when the output pin calls Prepare on us. The shared memory
  276. // blocks are used in subsequent calls to GDI CreateDIBSection, once that
  277. // has been done the output pin can fill the buffers with data which will
  278. // then be handed to GDI through BitBlt calls and thereby remove one copy
  279.  
  280. class CImageAllocator : public CBaseAllocator
  281. {
  282. protected:
  283.  
  284.     CBaseFilter *m_pFilter;   // Delegate reference counts to
  285.     CMediaType *m_pMediaType;           // Pointer to the current format
  286.  
  287.     // Used to create and delete samples
  288.  
  289.     HRESULT Alloc();
  290.     void Free();
  291.  
  292.     // Manage the shared DIBSECTION and DCI/DirectDraw buffers
  293.  
  294.     HRESULT CreateDIB(LONG InSize,DIBDATA &DibData);
  295.     STDMETHODIMP CheckSizes(ALLOCATOR_PROPERTIES *pRequest);
  296.     virtual CImageSample *CreateImageSample(LPBYTE pData,LONG Length);
  297.  
  298. public:
  299.  
  300.     // Constructor and destructor
  301.  
  302.     CImageAllocator(CBaseFilter *pFilter,TCHAR *pName,HRESULT *phr);
  303. #ifdef DEBUG
  304.     ~CImageAllocator();
  305. #endif
  306.  
  307.     STDMETHODIMP_(ULONG) NonDelegatingAddRef();
  308.     STDMETHODIMP_(ULONG) NonDelegatingRelease();
  309.     void NotifyMediaType(CMediaType *pMediaType);
  310.  
  311.     // Agree the number of buffers to be used and their size
  312.  
  313.     STDMETHODIMP SetProperties(
  314.         ALLOCATOR_PROPERTIES *pRequest,
  315.         ALLOCATOR_PROPERTIES *pActual);
  316. };
  317.  
  318.  
  319. // This class is a fairly specialised helper class for image renderers that
  320. // have to create and manage palettes. The CBaseWindow class looks after
  321. // realising palettes once they have been installed. This class can be used
  322. // to create the palette handles from a media format (which must contain a
  323. // VIDEOINFO structure in the format block). We try to make the palette an
  324. // identity palette to maximise performance and also only change palettes
  325. // if actually required to (we compare palette colours before updating).
  326. // All the methods are virtual so that they can be overriden if so required
  327.  
  328. class CImagePalette
  329. {
  330. protected:
  331.  
  332.     CBaseWindow *m_pBaseWindow;             // Window to realise palette in
  333.     CBaseFilter *m_pFilter;                 // Media filter to send events
  334.     CDrawImage *m_pDrawImage;               // Object who will be drawing
  335.     HPALETTE m_hPalette;                    // The palette handle we own
  336.  
  337. public:
  338.  
  339.     CImagePalette(CBaseFilter *pBaseFilter,
  340.                   CBaseWindow *pBaseWindow,
  341.                   CDrawImage *pDrawImage);
  342.  
  343. #ifdef DEBUG
  344.     virtual ~CImagePalette();
  345. #endif
  346.  
  347.     static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice);
  348.     HRESULT RemovePalette();
  349.     static HRESULT MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice);
  350.     HRESULT CopyPalette(const CMediaType *pSrc,CMediaType *pDest);
  351.     BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo);
  352.     HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,LPSTR szDevice);
  353.  
  354.     BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, LPRECT lprcSrc, LPRECT lprcDst)
  355.     {
  356.         return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst);
  357.     }
  358. };
  359.  
  360.  
  361. // Another helper class really for video based renderers. Most such renderers
  362. // need to know what the display format is to some degree or another. This
  363. // class initialises itself with the display format. The format can be asked
  364. // for through GetDisplayFormat and various other accessor functions. If a
  365. // filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE
  366. // message then it can call RefreshDisplayType to reset that format). Also
  367. // many video renderers will want to check formats as they are proposed by
  368. // source filters. This class provides methods to check formats and only
  369. // accept those video formats that can be efficiently drawn using GDI calls
  370.  
  371. class CImageDisplay : public CCritSec
  372. {
  373. protected:
  374.  
  375.     // This holds the display format; biSize should not be too big, so we can
  376.     // safely use the VIDEOINFO structure
  377.     VIDEOINFO m_Display;
  378.  
  379.     static DWORD CountSetBits(const DWORD Field);
  380.     static DWORD CountPrefixBits(const DWORD Field);
  381.     static BOOL CheckBitFields(const VIDEOINFO *pInput);
  382.  
  383. public:
  384.  
  385.     // Constructor and destructor
  386.  
  387.     CImageDisplay();
  388.  
  389.     // Used to manage BITMAPINFOHEADERs and the display format
  390.  
  391.     const VIDEOINFO *GetDisplayFormat();
  392.     HRESULT RefreshDisplayType(LPSTR szDeviceName);
  393.     static BOOL CheckHeaderValidity(const VIDEOINFO *pInput);
  394.     static BOOL CheckPaletteHeader(const VIDEOINFO *pInput);
  395.     BOOL IsPalettised();
  396.     WORD GetDisplayDepth();
  397.  
  398.     // Provide simple video format type checking
  399.  
  400.     HRESULT CheckMediaType(const CMediaType *pmtIn);
  401.     HRESULT CheckVideoType(const VIDEOINFO *pInput);
  402.     HRESULT UpdateFormat(VIDEOINFO *pVideoInfo);
  403.     const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo);
  404.  
  405.     BOOL GetColourMask(DWORD *pMaskRed,
  406.                        DWORD *pMaskGreen,
  407.                        DWORD *pMaskBlue);
  408. };
  409.  
  410. //  Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2
  411. STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt);
  412.  
  413. #endif // __WINUTIL__
  414.  
  415.